package com.rain.builder;

import com.rain.bean.FieldInfo;
import com.rain.bean.TableInfo;
import com.rain.utils.Constants;
import com.rain.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.beans.Introspector;
import java.io.*;
import java.util.List;
import java.util.Map;

public class BuildServiceImpl {

    private static final Logger logger = LoggerFactory.getLogger(BuildService.class);

    public static void execute(TableInfo tableInfo) throws IOException {
        File folder = new File(Constants.PACKAGE_SERVICE_IMPL_PATH);
        if(!folder.exists()){
            folder.mkdirs();
        }

        File file = new File(folder,tableInfo.getBeanName() + "ServiceImpl.java");

        try{
            file.createNewFile();
        }catch(IOException e){
            e.printStackTrace();
        }

        OutputStream outputStream = null;
        OutputStreamWriter outputStreamWriter = null;
        BufferedWriter bufferedWriter = null;

        try{
            outputStream = new FileOutputStream(file);
            outputStreamWriter = new OutputStreamWriter(outputStream,"UTF-8");
            bufferedWriter = new BufferedWriter(outputStreamWriter);
            // 基本模版
            bufferedWriter.write("package " + Constants.PACKAGE_SERVICE_IMPL + ";");
            bufferedWriter.newLine();
            bufferedWriter.newLine();

            // 判断是否添加日期类
            if(tableInfo.getHaveDate() || tableInfo.getHaveDateTime()){
                bufferedWriter.write("import java.util.Date;");
                bufferedWriter.newLine();
                bufferedWriter.write(Constants.BEAN_DATE_FORMAT_CLASS + ";");
                bufferedWriter.newLine();
                bufferedWriter.write(Constants.BEAN_DATE_UNFORMAT_CLASS + ";");
                bufferedWriter.newLine();
                bufferedWriter.write("import " + Constants.PACKAGE_ENUM +".DateTimePatternEnum;");
                bufferedWriter.newLine();
                bufferedWriter.write("import " + Constants.PACKAGE_UTILS +".DateUtil;");
                bufferedWriter.newLine();

            }

            bufferedWriter.write("import " + Constants.PACKAGE_ENUM +".PageSize;");
            bufferedWriter.newLine();
            bufferedWriter.write("import " + Constants.PACKAGE_QUERY + "." + "SimplePage" + ";");
            bufferedWriter.newLine();
            bufferedWriter.write("import " + Constants.PACKAGE_ENTITY + "." + tableInfo.getBeanName() + ";");
            bufferedWriter.newLine();
            bufferedWriter.write("import " + Constants.PACKAGE_QUERY + "." + tableInfo.getBeanParamName() + ";");
            bufferedWriter.newLine();
            bufferedWriter.write("import " + Constants.PACKAGE_QUERY + "." + "PaginationResult" + ";");
            bufferedWriter.newLine();
            bufferedWriter.write("import " + Constants.PACKAGE_MAPPER + "." + tableInfo.getBeanName() + "Mapper" + ";");
            bufferedWriter.newLine();
            bufferedWriter.write("import " + Constants.PACKAGE_SERVICE + "." + tableInfo.getBeanName() + "Service" + ";");
            bufferedWriter.newLine();
            bufferedWriter.write("import org.springframework.stereotype.Service;");
            bufferedWriter.newLine();
            bufferedWriter.newLine();

            bufferedWriter.write("import javax.annotation.Resource;");
            bufferedWriter.newLine();
            bufferedWriter.write("import java.util.List;");
            bufferedWriter.newLine();

            BuildComment.createClassComment(bufferedWriter, tableInfo.getComment() + "Service");
            bufferedWriter.newLine();
            bufferedWriter.write("@Service(\"" + Introspector.decapitalize(tableInfo.getBeanName() + "Service") +  "\")\n");
            bufferedWriter.write("public class " + tableInfo.getBeanName() + "Service" + "Impl implements " + tableInfo.getBeanName() + "Service" + "{\n\n");

            bufferedWriter.write("\t@Resource\n");
            bufferedWriter.write("\tprivate " + tableInfo.getBeanName() + "Mapper<" + tableInfo.getBeanName() + ", " + tableInfo.getBeanParamName() +  "> " + Introspector.decapitalize(tableInfo.getBeanName() + "Mapper") + ";\n\n");


            BuildComment.createFieldComment(bufferedWriter,"根据条件查询列表");
            bufferedWriter.write("\tpublic List<" + tableInfo.getBeanName() + "> findListByParam(" + tableInfo.getBeanParamName() + " query) {\n\n");
            bufferedWriter.write("\t\treturn this." + Introspector.decapitalize(tableInfo.getBeanName() + "Mapper") + ".selectList(query)" + ";\n\n");
            bufferedWriter.write("\t}\n\n");

            BuildComment.createFieldComment(bufferedWriter,"根据条件查询数量");
            bufferedWriter.write("\tpublic Long findCountByParam(" + tableInfo.getBeanParamName() + " query) {\n\n");
            bufferedWriter.write("\t\treturn this." + Introspector.decapitalize(tableInfo.getBeanName() + "Mapper") + ".selectCount(query)" + ";\n\n");
            bufferedWriter.write("\t}\n\n");

            BuildComment.createFieldComment(bufferedWriter,"分页查询");
            bufferedWriter.write("\tpublic PaginationResult<" + tableInfo.getBeanName() + "> findListByPage(" + tableInfo.getBeanParamName() + " query) {\n\n");

            bufferedWriter.write("\t\tLong count = " + Introspector.decapitalize(tableInfo.getBeanName() + "Mapper") + ".selectCount(query);\n");
            bufferedWriter.write("\t\tInteger pageNo = query.getPageNo() == null ? 1 : query.getPageNo();\n");
            bufferedWriter.write("\t\tInteger pageSize = query.getPageSize() == null ? PageSize.SIZE15.getSize() : query.getPageSize();\n");
            bufferedWriter.write("\t\tSimplePage simplePage = new SimplePage(query.getPageNo(), query.getPageSize(), count);\n");
            bufferedWriter.write("\t\tquery.setSimplePage(simplePage);\n");
            bufferedWriter.write("\t\tList<" + tableInfo.getBeanName() + "> list = " + Introspector.decapitalize(tableInfo.getBeanName() + "Mapper")  + ".selectList(query);\n");
            bufferedWriter.write("\t\tPaginationResult<" + tableInfo.getBeanName() + "> result = new PaginationResult(count, simplePage.getPageNo(), simplePage.getPageSize(), simplePage.getPageTotal(),list);\n");
            bufferedWriter.write("\t\treturn result;\n\n");

            bufferedWriter.write("\t}\n\n");

            BuildComment.createFieldComment(bufferedWriter,"新增");
            bufferedWriter.write("\tpublic Integer add(" + tableInfo.getBeanName() + " bean) {\n\n");
            bufferedWriter.write("\t\treturn " + Introspector.decapitalize(tableInfo.getBeanName() + "Mapper") + ".insert(bean)" + ";\n\n");
            bufferedWriter.write("\t}\n\n");

            BuildComment.createFieldComment(bufferedWriter,"批量新增");
            bufferedWriter.write("\tpublic Integer addBatch(List<" + tableInfo.getBeanName() + "> listBean) {\n\n");
            bufferedWriter.write("\t\tif(listBean == null || listBean.isEmpty()) {\n");
            bufferedWriter.write("\t\treturn 0;\n");
            bufferedWriter.write("\t\t}\n");
            bufferedWriter.write("\t\treturn " + Introspector.decapitalize(tableInfo.getBeanName() + "Mapper") + ".insertBatch(listBean)" + ";\n\n");
            bufferedWriter.write("\t}\n\n");

            BuildComment.createFieldComment(bufferedWriter,"批量新增修改");
            bufferedWriter.write("\tpublic Integer addOrUpdateBatch(List<" + tableInfo.getBeanName() + "> listBean) {\n\n");
            bufferedWriter.write("\t\tif(listBean == null || listBean.isEmpty()) {\n");
            bufferedWriter.write("\t\treturn 0;\n");
            bufferedWriter.write("\t\t}\n");
            bufferedWriter.write("\t\treturn " + Introspector.decapitalize(tableInfo.getBeanName() + "Mapper") + ".insertOrUpdateBatch(listBean);" + "\n\n");
            bufferedWriter.write("\t}\n\n");

            for (Map.Entry<String, List<FieldInfo>> entry: tableInfo.getKeyIndexMap().entrySet()) {
                List<FieldInfo> value = entry.getValue();
                Integer index = 0;
                StringBuffer stringBufferName = new StringBuffer();
                StringBuffer stringBufferParam = new StringBuffer();
                StringBuffer stringBufferReturnParam = new StringBuffer();
                for (FieldInfo fieldInfo : value) {
                    index++;
                    stringBufferName.append(StringUtils.uperCaseFirstLetter(fieldInfo.getPropertyName()));
                    if(index < value.size()){
                        stringBufferName.append("And");
                    }

                    stringBufferParam.append(fieldInfo.getJavaType() + " " + fieldInfo.getPropertyName());
                    stringBufferReturnParam.append(fieldInfo.getPropertyName());
                    if(index < value.size()){
                        stringBufferParam.append(", ");
                        stringBufferReturnParam.append(", ");
                    }
                }
                BuildComment.createFieldComment(bufferedWriter,"根据" + stringBufferName + "查询");
                bufferedWriter.write("\tpublic " + tableInfo.getBeanName() + " get"+ tableInfo.getBeanName() +"By" + stringBufferName + "(" + stringBufferParam + ") {\n\n");
                bufferedWriter.write("\t\treturn " + Introspector.decapitalize(tableInfo.getBeanName() + "Mapper") + ".selectBy" + stringBufferName + "(" + stringBufferReturnParam + ")" + ";\n\n");
                bufferedWriter.write("\t}\n\n");

                BuildComment.createFieldComment(bufferedWriter,"根据" + stringBufferName + "更新");
                bufferedWriter.write("\tpublic Integer update"+ tableInfo.getBeanName() +"By" + stringBufferName + "(" + tableInfo.getBeanName() + " bean, " + stringBufferParam + "){\n\n");
                bufferedWriter.write("\t\treturn " + Introspector.decapitalize(tableInfo.getBeanName() + "Mapper") + ".updateBy" + stringBufferName + "(bean, "  + stringBufferReturnParam + ")" + ";\n\n");

                bufferedWriter.write("\t}\n\n");

                BuildComment.createFieldComment(bufferedWriter,"根据" + stringBufferName + "删除");
                bufferedWriter.write("\tpublic Integer delete"+ tableInfo.getBeanName() +"By" + stringBufferName + "(" + stringBufferParam + ") {\n\n");
                bufferedWriter.write("\t\treturn " + Introspector.decapitalize(tableInfo.getBeanName() + "Mapper") + ".deleteBy" + stringBufferName + "(" + stringBufferReturnParam + ")" + ";\n\n");

                bufferedWriter.write("\t}\n\n");
            }

            bufferedWriter.write("}");


            bufferedWriter.flush();
        }catch (Exception e){
            logger.info("创建Service失败", e.getMessage());
            e.printStackTrace();
        }finally {
            if(bufferedWriter != null) {
                bufferedWriter.close();
            }
            if(outputStreamWriter != null) {
                outputStreamWriter.close();
            }
            if(outputStream != null) {
                outputStream.close();
            }
        }
    }
}
